"""
Case Type   : 极致RTO支持备机可读
Case Name   : 传统集群，创建普通行存段页式表(结合tpcc)，开启极致RTO场景下验证备机可读
Create At   : 2025/03
Owner       : haomeng
Description :
    1、集群内开启极致RTO特性，重启使其生效
    2、主节点执行tpcc读写业务
    3、稍后备机执行只读业务
    4、对比主备机数据一致性
    5、清理环境，恢复环境初始状态
Expect      :
    1、设置成功，重启成功
    2、主机读写业务成功
    3、备机执行只读业务成功
    4、主备机数据一致
    5、清理成功，恢复环境成功
History     :
"""

import os
import time
import unittest

from testcase.utils.Common import Common
from testcase.utils.CommonSH import CommonSH
from testcase.utils.CommonSH import RestartDbCluster
from testcase.utils.Constant import Constant
from testcase.utils.Logger import Logger
from yat.test import Node
from yat.test import macro


class RTOStandbyRead(unittest.TestCase):
    nodes_tuple = ('PrimaryDbUser', 'Standby1DbUser', 'Standby2DbUser')

    @RestartDbCluster(*nodes_tuple)
    def setUp(self):
        self.log = Logger()
        self.log.info(f'----{os.path.basename(__file__)} start----')
        self.root_user = Node(node='PrimaryRoot')
        self.comsh_user = [CommonSH('PrimaryDbUser'), CommonSH('Standby1DbUser'), CommonSH('Standby2DbUser')]
        self.com = Common()
        self.constant = Constant()

        self.param_list = ['recovery_parse_workers', 'recovery_redo_workers']
        self.value_list = ['4', '4']
        self.default_value = []
        self.table_list = ['bmsql_config', 'bmsql_customer', 'bmsql_district', 'bmsql_history',
                           'bmsql_item', 'bmsql_new_order', 'bmsql_oorder', 'bmsql_order_line',
                           'bmsql_stock', 'bmsql_warehouse']

    def test_rto_standby_read(self):
        text = '-----step1:集群内开启极致RTO特性，重启使其生效;  expect:设置成功，重启成功-----'
        self.log.info(text)

        for param in self.param_list:
            value = self.comsh_user[0].executDbSql(f'show {param}')
            self.default_value.append(value.splitlines()[-2].strip())
        self.log.info(self.default_value)

        for param in self.param_list:
            set_param = self.comsh_user[0].executeGsguc('set',
                        self.constant.GSGUC_SUCCESS_MSG, f'{param} = {self.value_list[self.param_list.index(param)]}')
            self.log.info(set_param)
            self.assertTrue(set_param, '参数设置失败')

        self.log.info('---重启集群使参数生效---')
        restart = self.comsh_user[0].om_restart()
        self.log.info(restart)
        self.assertTrue(restart, '集群重启失败')

        self.log.info('---查看参数值修改是否成功---')
        for param in self.param_list:
            value = self.comsh_user[0].executDbSql(f'show {param};')
            self.assertEqual(value.splitlines()[-2].strip(),
                             self.value_list[self.param_list.index(param)], '参数未修改成功')

        text = '-----step2:主节点执行tpcc读写业务  expect:业务执行成功-----'
        self.log.info(text)

        tpcc_cmd = f'./runBenchmark.sh {macro.TPCC_PROPS_FILENAME}'
        self.log.info(tpcc_cmd)

        tpcc_execute = self.com.startTPCC(self.root_user, f'{macro.TPCC_PATH}', tpcc_cmd)
        self.log.info(tpcc_execute)
        self.assertIn(self.constant.TPCC_SUCCESS_MSG, tpcc_execute, 'tpcc执行失败')

        text = '-----step3:备节点查看表数据  expect:查看成功-----'
        self.log.info(text)

        self.log.info('---等待备机数据同步---')
        flag = self.comsh_user[0].check_data_consistency()
        self.assertTrue(flag, '数据同步失败')

        sta_res_list = []
        for table in self.table_list:
            sta_sql = f"select count(*) from {table};"
            self.log.info(sta_sql)
            sta_res = self.comsh_user[1].executDbSql(sta_sql)
            self.log.info(sta_res)
            sta_res_list.append(sta_res)
            self.assertNotIn('(0 rows)', sta_res, '查询结果异常')

        text = '-----step4:对比主备机数据一致性  expect:查看成功，与主机数据一致-----'
        self.log.info(text)

        pri_res_list = []
        for table in self.table_list:
            sql = f"select count(*) from {table};"
            self.log.info(sql)
            pri_res = self.comsh_user[0].executDbSql(sql)
            self.log.info(pri_res)
            pri_res_list.append(pri_res)
            self.assertNotIn('(0 rows)', pri_res, '查询结果异常')

        time.sleep(5)
        self.assertEqual(pri_res_list, sta_res_list, '主备查询结果不一致')

    def tearDown(self):
        text = '-----step5:清理环境，恢复环境初始状态  expect:清理成功，恢复环境成功-----'
        self.log.info(text)

        for param in self.param_list:
            reset_param = self.comsh_user[0].executeGsguc('set',
                                                    self.constant.GSGUC_SUCCESS_MSG,
                                                    f'{param} = {self.default_value[self.param_list.index(param)]}')
            self.log.info(reset_param)

        restart = self.comsh_user[0].om_restart(False)
        self.log.info(restart)

        for param in self.param_list:
            reset_value = self.comsh_user[0].executDbSql(f'show {param};')
            self.log.info(reset_value)
            self.assertEqual(reset_value.splitlines()[-2].strip(),
                             self.default_value[self.param_list.index(param)], '参数恢复失败')
        self.log.info(f'----{os.path.basename(__file__)} end----')
